#!/usr/bin/env python

# ***** BEGIN LICENSE BLOCK *****
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
#
# The contents of this file are subject to the Mozilla Public License Version
# 1.1 (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
# http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
# for the specific language governing rights and limitations under the
# License.
#
# The Original Code is mozilla.org code.
#
# Contributor(s):
#   Chris Jones <jones.chris.g@gmail.com>
#
# Alternatively, the contents of this file may be used under the terms of
# either of the GNU General Public License Version 2 or later (the "GPL"),
# or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
# in which case the provisions of the GPL or the LGPL are applicable instead
# of those above. If you wish to allow use of your version of this file only
# under the terms of either the GPL or the LGPL, and not to allow others to
# use your version of this file under the terms of the MPL, indicate your
# decision by deleting the provisions above and replace them with the notice
# and other provisions required by the GPL or the LGPL. If you do not delete
# the provisions above, a recipient may use your version of this file under
# the terms of any one of the MPL, the GPL or the LGPL.
#
# ***** END LICENSE BLOCK *****

import getopt, os, re, sys

# find out where pork was installed

_verbosity = 1
def log(minv, fmt, *args):
    if _verbosity >= minv:
        print >>sys.stderr, fmt % args

def getcallerpath():
    '''Return the absolute path of the file containing the code that
**CALLED** this function.'''
    return sys._getframe(1).f_code.co_filename

installdir, _ = os.path.split(getcallerpath())
sys.path.append(installdir)
import porky

# process command line

def usage(err):
    if err:
        out, rv = (sys.stderr, 1)
    else:
        out, rv = (sys.stdout, 0)
    print >>out, '''
Usage:  porkyc [OPTIONS...] REWRITE_SPEC...

where OPTIONS are zero or more of
  -h, --help
          : print this message and exit
  -o DIR, --output-dir=DIR
          : directory in which to put generated code.
              Created if it doesn't exist.
            default: choose directory name based on rewrite spec
  -S, --gencode-only
          : Just generate the code; don't compile it.
            default: generate *and* compile.
  -v N, --verbosity=N
          : be as verbose as N.  set to 0 for no output, and higher than 1
              for more output.
            default: -v 1

and REWRITE_SPEC is one of
  -e EXPR, --expr=EXPR
          : generate a temporary rewriter from the rewrite expression EXPR
              Any number of EXPRs can be specified.
  PROGRAM
          : generate a named rewriter from the rewrite program PROGRAM.
              PROGRAM can be "-", in which case the program is read from stdin.
              Only *one* program can be specified, and cannot be combined
              with EXPRs.
  default : read specification from stdin
'''
    sys.exit(rv)

try:
    opts, args = getopt.gnu_getopt(
        sys.argv[1:],
        'ho:v:e:S',
        ['help',
         'output-dir=',
         'gencode-only'
         'verbosity=',
         'expr=',
         'program='])
except getopt.GetoptError, err:
    print >>sys.stderr, str(err), '\n'
    usage(err=True)

codedir = None
genonly = False
expr = ''
prog = '-'

for o, a in opts:
    if o in ('-h', '--help'):
        usage(err=False)
    elif o in ('-o', '--output-dir'):
        codedir = a
    elif o in ('-p', '--output-patch'):
        patchout = a
    elif o in ('-v', '--verbosity'):
        _verbosity = int(a)
    elif o in ('-S', '--gencode-only'):
        genonly = True
    elif o in ('-e', '--expr'):
        if prog != '-':
            print >>sys.stderr, 'only one rewrite program can be specified'
            usage(err=True)
        expr += a +';'

if len(args):
    if 1 != len(args):
        print >>sys.stderr, 'only one rewrite program can be specified'
        usage(err=True)
    if expr != '':
        print >>sys.stderr, 'rewrite programs cannot be combined with expressions'
        usage(err=True)
    prog = args[0]

specstring = None
if expr != '':
    log (1, 'using immediate rewrite expression(s)')
    specstring = '''rewrite PorkyTempRewrite {
%s
}'''% ('\n'.join(expr.split(';')))
elif prog != '-':
    log (1, 'using rewrite program %s', prog)
    specstring = open(prog, 'r').read()
else:
    log(1, 'reading rewrite spec from stdin')
    specstring = sys.stdin.read()

log(3, 'rewrite spec:\n%s', specstring)

log(1, 'parsing rewrite spec')
rewriter = porky.parse(specstring)

if codedir is None:
    codedir = rewriter.name +'.code'
log(1, 'generating code')
writtento = porky.genrewriter(rewriter, codedir)
log(1, 'code written to "%s"', writtento)

if genonly:
    sys.exit(0)

os.chdir(writtento)
os.execlp('make', 'all')
